﻿using Chemistry.Models;
using Chemistry.Tools;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Newtonsoft.Json;

namespace Chemistry.ViewModels
{
    public class ConfigScoreViewModel:VmBase
    {
        #region  属性

        private List<Workflow> _workflows;

        private int _min_index;
        private int _max_index;
        private int _min_index2;
        private int _max_index2;

        private ObservableCollection<PropertyNodeItem> nodes;
        public ObservableCollection<PropertyNodeItem> NodeList
        {
            get { return nodes; }
            set { nodes = value; RaisePropertyChanged("NodeList"); }
        }

        public Workflow SelectedWorkFlow { get; set; }

        private ObservableCollection<Detail> _details;

        public ObservableCollection<Detail> Details
        {
            get { return _details; }
            set { _details = value; RaisePropertyChanged("Details"); }
        }

        private ObservableCollection<Abnormal> _abnormals;

        public ObservableCollection<Abnormal> Abnormals
        {
            get { return _abnormals; }
            set { _abnormals = value; RaisePropertyChanged("Abnormals"); }
        }

        private Abnormal _selectedAbnormal;

        public Abnormal SelectedAbnormal
        {
            get { return _selectedAbnormal; }
            set
            {
                _selectedAbnormal = value;
                RaisePropertyChanged("SelectedAbnormal");
            }
        }

        private Detail _detail;

        public Detail SelectedDetail
        {
            get { return _detail; }
            set
            {
                _detail = value;
                RaisePropertyChanged("SelectedDetail");
            }
        }
        #endregion


        #region 按钮 Enabled
        private bool _isupEnabled;

        public bool IsUpEnabled
        {
            get { return _isupEnabled; }
            set { _isupEnabled = value; RaisePropertyChanged("IsUpEnabled"); }
        }

        private bool _isdownEnabled;

        public bool IsDownEnabled
        {
            get { return _isdownEnabled; }
            set { _isdownEnabled = value; RaisePropertyChanged("IsDownEnabled"); }
        }

        private bool _isupEnabled2;

        public bool IsUpEnabled2
        {
            get { return _isupEnabled2; }
            set { _isupEnabled2 = value; RaisePropertyChanged("IsUpEnabled2"); }
        }

        private bool _isdownEnabled2;

        public bool IsDownEnabled2
        {
            get { return _isdownEnabled2; }
            set { _isdownEnabled2 = value; RaisePropertyChanged("IsDownEnabled2"); }
        }

        private bool _isDeleteDetailEnbaled;

        public bool IsDeleteDetailEnabled
        {
            get { return _isDeleteDetailEnbaled; }
            set { _isDeleteDetailEnbaled = value; RaisePropertyChanged("IsDeleteDetailEnabled"); }
        }

        private bool _isDeleteAbnormalEnabled;

        public bool IsDeleteAbnormalEnabled
        {
            get { return _isDeleteAbnormalEnabled; }
            set { _isDeleteAbnormalEnabled = value; RaisePropertyChanged("IsDeleteAbnormalEnabled"); }
        }

        #endregion

        public RelayCommand UpCommand { get; set; }
        public RelayCommand DownCommand { get; set; }
        public RelayCommand DeleteDetailCommand { get; set; }

        public RelayCommand UpCommand2 { get; set; }
        public RelayCommand DownCommand2 { get; set; }
        public RelayCommand DeleteAbnormal { get; set; }
        public RelayCommand CommitCommand2 { get; set; }

        public ConfigScoreViewModel()
        {
            InitFlows();
            UpCommand = new RelayCommand(UpExec, () => SelectedDetail != null && SelectedDetail.Index > _min_index);
            DownCommand = new RelayCommand(DownExec, () => SelectedDetail != null && SelectedDetail.Index < _max_index);
            DeleteDetailCommand = new RelayCommand(DeleteDetailExec, ()=> SelectedDetail!=null); 
            //CommitCommand = new RelayCommand(CommitExec,()=> this.Details!=null&& this.Details.Count>0);
            CommitCommand = new RelayCommand(CommitExec, () => this.Details != null && this.Details.Count > 0);


            UpCommand2 = new RelayCommand(UpExec2,()=>SelectedAbnormal!=null && SelectedAbnormal.Index>_min_index2);
            DownCommand2 = new RelayCommand(DownExec2, () => SelectedAbnormal != null && SelectedAbnormal.Index < _max_index2);
            DeleteAbnormal = new RelayCommand(DeleteAbnormalExec,()=>SelectedAbnormal!=null);
            CommitCommand2 = new RelayCommand(CommitExec2,()=>Abnormals!=null&& Abnormals.Count>0);

            InitMessage();
        }

        private void CommitExecTest()
        {
           // SelectedWorkFlow.Details = Details as List<Detail>;
           // var data = JsonConvert.SerializeObject(workflows, Formatting.Indented);
            using (FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory +"score.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                using (StreamWriter sw =new StreamWriter(fs))
                {
                    var data = JsonConvert.SerializeObject(_workflows, Formatting.Indented);
                    sw.Write(data);
                }
                
            }
        }

        private void InitMessage()
        {
            Register<PropertyNodeItem>(this, MessageToken.SelectFlow, (i) => {
                SelectedWorkFlow = i.Tag as Workflow;
                 FreshDetail(SelectedWorkFlow.Id);
                 FreshAbnormal(SelectedWorkFlow.Id);
            });
        }

        #region 异常  命令方法
        private async void CommitExec2()
        {
            if (this.Abnormals == null || this.Abnormals.Count == 0) return;

            int index = 1;


            var currentList = _workflows.SingleOrDefault(i => i.Id == SelectedWorkFlow.Id).Abnormals;
            currentList.Clear();
            foreach (var item in Abnormals)
            {
                if (currentList.Count(i => i.Description == item.Description) == 0)
                {
                    currentList.Add(new Abnormal() {Index = index, Description = item.Description, Rate = item.Rate, Value =  item.Value, Operator = item.Operator});
                    index++;
                }
            }

            Save();


            //foreach (var item in Abnormals)
            //{
            //    if (item.Id == 0)
            //    {
            //        index++;
            //        item.Index = index;
            //        item.WorkFlowId = SelectedWorkFlow.Id;
            //    }
            //    else
            //    {
            //        index = item.Index;
            //    }
            //}
            //string request_url = string.Format("{0}/ModifyAbnormal", workflow_url);
            //var result = await HttpBaseChemistry.PostAsJsonAsync<ChemistryApiReuslt>(request_url, this.Abnormals.ToList());
            //if (result.status == 1)
            //{
            //    ShowMessage("已添加相同的步骤，请重新检查步骤是否重复");
            //}
            //else if (result.status == -3)
            //{
            //    ShowMessage("服务器内部错误，请联系管理员");
            //}
            //int flowid = SelectedWorkFlow.Id;
            FreshAbnormal(SelectedWorkFlow.Id);
        }


        private void DeleteAbnormalExec()
        {
            if (SelectedAbnormal != null)
            {
                _workflows.SingleOrDefault(i => i.Id == SelectedWorkFlow.Id).Abnormals.Remove(SelectedAbnormal);
                Abnormals.Remove(SelectedAbnormal);
            }


            //if (SelectedAbnormal.Id == 0)
            //{
            //    Abnormals.Remove(SelectedAbnormal);
            //}
            //else
            //{
            //    string request_url = string.Format("{0}/DeleteAbnormal?abnormalid={1}", workflow_url, SelectedAbnormal.Id);
            //    var message = await HttpBaseChemistry.GetAsync<string>(request_url);

            //    if (!string.IsNullOrEmpty(message))
            //        ShowMessage("错误" + message);
            //    else
            //    {
            //        FreshAbnormal(SelectedWorkFlow.Id);
            //    }
            //}
        }

        private void DownExec2()
        {
            int nextIndex = SelectedAbnormal.Index + 1;
            Abnormals.SingleOrDefault(i => i.Index == nextIndex).Index--;
            SelectedAbnormal.Index++;
            var result = Abnormals.OrderBy(i => i.Index);
            Abnormals = new ObservableCollection<Abnormal>(result);
        }

        private void UpExec2()
        {
            int nextIndex = SelectedAbnormal.Index - 1;
            Abnormals.SingleOrDefault(i => i.Index == nextIndex).Index++;
            SelectedAbnormal.Index--;
            var result = Abnormals.OrderBy(i => i.Index);
            Abnormals = new ObservableCollection<Abnormal>(result);
        } 
        #endregion

        #region 步骤 命令方法
        private void DeleteDetailExec()
        {
            if (SelectedDetail != null)
            {
                _workflows.SingleOrDefault(i => i.Id == SelectedWorkFlow.Id).Details.Remove(SelectedDetail);
                Details.Remove(SelectedDetail);
            }
               
            //if (SelectedDetail.Id == 0)
            //{
            //    Details.Remove(SelectedDetail);
            //}
            //else
            //{
            //    try
            //    {
            //        string request_url = string.Format("{0}/DeleteDetail?detailid={1}", workflow_url, SelectedDetail.Id);
            //        var message = await HttpBaseChemistry.GetAsync<ChemistryApiReuslt>(request_url);
                    
            //    }
            //    catch (Exception ex)
            //    {
            //        AppendExecptionAsync(ex);
            //        ShowMessage("错误：" + ex.Message);
            //    }
            //}
        }

        private void DownExec()
        {
            int nextIndex = SelectedDetail.Index + 1;
           Details.SingleOrDefault(i => i.Index == nextIndex).Index--;
            SelectedDetail.Index++;
            var result = Details.OrderBy(i => i.Index);
            Details = new ObservableCollection<Detail>(result);
        }


        private void UpExec()
        {
            int prevIndex = SelectedDetail.Index - 1;
            Details.SingleOrDefault(i => i.Index == prevIndex).Index++;
            SelectedDetail.Index--;
            var result = Details.OrderBy(i => i.Index);
            Details = new ObservableCollection<Detail>(result);
        }
        private void CommitExec()
        {
            int index = 1;

            var currentList = _workflows.SingleOrDefault(i => i.Id == SelectedWorkFlow.Id).Details;
            currentList.Clear();
            foreach (var item in Details)
            {
                if (currentList.Count(i=>i.Step==item.Step)==0)
                {
                    currentList.Add(new Detail() { Index = index, Step = item.Step, Score = item.Score });
                    index++;
                }
            }

            Save();
            FreshDetail(SelectedWorkFlow.Id);
            //string request_url = string.Format("{0}/ModifyDetail", workflow_url);
            //try
            //{
            //    var result = await HttpBaseChemistry.PostAsJsonAsync<ChemistryApiReuslt>(request_url, Details);
            //    if (result.status == 1)
            //    {
            //        ShowMessage("已添加相同的步骤，请重新检查步骤是否重复");
            //    }
            //    else if (result.status == -3)
            //    {
            //        ShowMessage("服务器内部错误，请联系管理员");
            //    }
            //    int flowid = SelectedWorkFlow.Id;
            //    await FreshDetail(flowid);
            //}
            //catch (Exception ex)
            //{
            //    AppendExecptionAsync(ex);
            //    ShowMessage(ex.Message);
            //}
        }

        private void Save()
        {
            using (FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "scoredata.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    var data = JsonConvert.SerializeObject(_workflows, Formatting.Indented);
                    sw.Write(data);
                }
            }
        }

        #endregion

        #region  方法
        void FreshAbnormal(int flowid)
        {
          //  var list =   await GetAbnormalByFlowId(flowid);.
            var list = _workflows.SingleOrDefault(i => i.Id == flowid).Abnormals;
            if (list != null && list.Count > 0)
            {
               // workflows.Workflows.Where(i => i.Id == flowid).SingleOrDefault().Abnormals = list;
                Abnormals = new ObservableCollection<Abnormal>(list);
                _min_index2 = Abnormals.Min(i => i.Index);
                _max_index2 = Abnormals.Max(i => i.Index);
            }
            else
            {
                _workflows.SingleOrDefault(i => i.Id == flowid).Abnormals = new List<Abnormal>();
                Abnormals = new ObservableCollection<Abnormal>();
            }
        }

       void FreshDetail(int flowid)
        {
       //     List<Detail> details = await GetDetailByFlowId(flowid);
            List<Detail> details = _workflows.SingleOrDefault(i => i.Id == flowid).Details;
           if(details==null)
               _workflows.SingleOrDefault(i => i.Id == flowid).Details = new List<Detail>();
            Details = new ObservableCollection<Detail>(details);
            //workflows.Workflows.Where(i => i.Id == flowid).SingleOrDefault().Details = details;
            if (Details != null && Details.Count > 0)
            {
                _min_index = details.Min(i => i.Index);
                _max_index = details.Max(i => i.Index);
            }
        }

        private async Task<List<Detail>> GetDetailByFlowId(int flowid)
        {
            List<Detail> details = null;
            try
            {
                string request_url = string.Format("{0}/GetDetailsByFlowId?flowId={1}", workflow_url, flowid);
                var result = await HttpBaseChemistry.GetAsync<DetaiApiModel>(request_url);
                if (result!=null&& result.status == 0)
                    details = result.details;
            }
            catch (Exception ex)
            {
                AppendExecptionAsync(ex);
            }
            return details;
        } 
        private   void InitFlows()
        {
            //string request_url = string.Format("{0}/GetWorkflow", workflow_url);
            //var workflowapi_result = await HttpBaseChemistry.GetAsync<WorkflowApiModel>(request_url);
            //if (workflowapi_result != null && workflowapi_result.status == 0)
            //{
            //    workflows = workflowapi_result;
            //    NodeList = new ObservableCollection<PropertyNodeItem>();
            //    var flows = workflowapi_result.Workflows;
            //    foreach (var item in flows)
            //    {
            //        PropertyNodeItem pitem = new PropertyNodeItem()
            //        {
            //            Name = item.Name,
            //            Tag = item
            //        };
            //        NodeList.Add(pitem);
            //    }
            //}


            using (
                FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "scoredata.txt", FileMode.Open,
                    FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                using (StreamReader sr = new StreamReader(fs, Encoding.Default))
                {
                    var data = sr.ReadToEnd();
                    var result = JsonConvert.DeserializeObject<List<Workflow>>(data);
                    _workflows = result;
                    NodeList = new ObservableCollection<PropertyNodeItem>();
                    foreach (var item in result)
                    {
                        PropertyNodeItem pitem = new PropertyNodeItem()
                        {
                            Name = item.Name,
                            Tag = item
                        };
                        NodeList.Add(pitem);
                    }
                }
            }
        }

        async Task<List<Abnormal>> GetAbnormalByFlowId(int flowId)
        {
            List<Abnormal> list =null;
            try
            {
                string request_url = string.Format("{0}/GetAbnormalsByFlowId?flowId={1}", workflow_url, flowId);
                var result = await HttpBaseChemistry.GetAsync<AbnormalApiModel>(request_url);
                if (result != null && result.status == 0)
                    list = result.abnormals;
            }
            catch (Exception ex)
            {
                AppendExecptionAsync(ex);
            }
            return list;
        }
        #endregion


    }
}
